<template>
	<div class="mk-configurable-table">
		<el-tooltip content="点击设置表格列" placement="top">
			<el-button @click="handleSetColumns" v-reclick="1000" icon="ele-Setting" class="table-setting" circle />
		</el-tooltip>
		<a-table v-bind="$attrs" :dataSource="data" :columns="showColumns" :pagination="pagination" :scroll="{ x: scrollWidth, y: scrollHeight }" />
		<!-- 编辑表格显示弹窗 -->
		<el-dialog v-model="dialogVisible" title="编辑表格显示" width="60%">
			<el-form :model="editColumns" label-width="100px">
				<VueDraggable ref="draggable" v-model="editColumns">
					<el-form-item v-for="(col, index) in editColumns" :key="col.key">
						<template #label>
							<div class="form-item-label">
								<el-tooltip effect="dark" content="可拖动排序表格列" placement="top-end">
									<span class="drag-icon">
										<el-icon>
											<DCaret />
										</el-icon>
									</span>
								</el-tooltip>
								<span>{{ col.title }}</span>
							</div>
						</template>
						<div class="form-item-content">
							<el-input v-model="col.title" style="width: 150px" placeholder="请输入显示名称">
								<template #prepend>名称</template>
							</el-input>
							<el-input v-model="col.width" style="width: 150px" placeholder="auto">
								<template #prepend>宽度</template>
							</el-input>
							<el-switch v-model="col.visible" active-color="#13ce66" inactive-color="#ff4949" active-text="显示" inactive-text="隐藏" />
						</div>
					</el-form-item>
				</VueDraggable>
			</el-form>
			<template #footer>
				<el-button @click="handleCancelEdit">取消</el-button>
				<el-button type="primary" @click="handleSaveEdit">保存</el-button>
			</template>
		</el-dialog>
	</div>
</template>
<script lang="ts" setup>
/**
 * 可以让用户自定义显示的表格
 */
/*
使用举例
<MkConfigurableTable :data="data" :columns="columns" tableName="输血申请_输血反应" />
 const data = ref([
	{
		time: '2022-01-01',
		variety: '白细胞',
		bloodType: 'A型',
		reaction: '红斑狼疮',
	},
]);
const columns: ConfigurableTableColumn[] = [
	{
		title: '时间',
		dataIndex: 'time',
		key: 'time',
		visible: true,
	},
	{
		title: '品种',
		dataIndex: 'variety',
		key: 'variety',
		visible: true,
	},
	{
		title: '血型',
		dataIndex: 'bloodType',
		key: 'bloodType',
		visible: true,
	},
	{
		title: '反应',
		dataIndex: 'reaction',
		key: 'reaction',
		visible: true,
	},
];
1.列的显示与隐藏:用户可以通过配置弹窗动态调整列的显示状态（通过 visible 属性）。这些配置会存储在 localStorage 中，下次加载时会恢复用户的设置。
2.动态列宽:如果需要动态调整列宽，可以在列配置中设置 width 属性（如 width: 'auto' 或 width: 120）。
3.拖动排序:用户可以通过拖动列的标题来调整列的顺序。
*/
import { DCaret } from '@element-plus/icons-vue';
import { VueDraggable } from 'vue-draggable-plus';
defineOptions({
	name: 'MkConfigurableTable',
});
/**
 * props
 */
const props = defineProps({
	data: {
		type: Array,
		default: () => [],
	},
	tableName: {
		type: String,
		default: '',
	},
	columns: {
		type: Array as PropType<ConfigurableTableColumn[]>,
		default: () => [],
	},
	pagination: {
		type: Object as PropType<false | { current: number; pageSize: number; showSizeChanger: boolean }>,
		default: false,
	},
	scrollWidth: {
		type: [Number, Boolean, String],
		default: 'max-content',
	},
	scrollHeight: {
		type: [Number, Boolean, String],
		default: true,
	},
});
/**
 * 所有的列
 */
const allColumns = ref<ConfigurableTableColumn[]>([]);
/**
 * 显示的列
 */
const showColumns = computed(() => {
	return allColumns.value.filter((col) => col.visible);
});
/**
 * 编辑的列
 */
const editColumns = ref<ConfigurableTableColumn[]>([]);
/**
 * 显示编辑弹窗
 */
const dialogVisible = ref(false);
/**
 * 设置显示的列
 */
const handleSetColumns = () => {
	editColumns.value = [];
	allColumns.value.forEach((col) => {
		editColumns.value.push({ ...col });
	});
	dialogVisible.value = true;
};
/**
 * 取消编辑
 */
const handleCancelEdit = () => {
	dialogVisible.value = false;
};
/**
 * 保存编辑
 */
const handleSaveEdit = () => {
	allColumns.value = [];
	editColumns.value.forEach((col) => {
		col.width = !col.width || isNaN(col.width as number) || col.width === '' || col.width === 'auto' ? 'auto' : ~~col.width;
		allColumns.value.push({ ...col });
	});
	window.localStorage.setItem(props.tableName + '_columns', JSON.stringify(allColumns.value));
	dialogVisible.value = false;
};
/**
 * 显示的列发生变化
 */
onMounted(() => {
	allColumns.value = [];
	let columnStr = window.localStorage.getItem(props.tableName + '_columns');
	if (columnStr) {
		allColumns.value = [...JSON.parse(columnStr)];
	}
	for (let col of props.columns) {
		if (!allColumns.value.find((item) => item.key === col.key)) {
			col.width = col.width ? col.width : 'auto';
			col.ellipsis = true;
			col.tooltip = true;
			allColumns.value.push(col);
		}
	}
	console.log('显示的列', props.columns, allColumns.value);
});
/**
 * 暴露
 */
defineExpose({});
</script>
<style lang="scss" scoped>
.mk-configurable-table {
	width: 100%;
	display: flex;
	flex-direction: column;
	position: relative;

	.table-setting {
		position: absolute;
		width: 1rem;
		height: 1rem;
		top: 0;
		left: 0;
		z-index: 3;
		opacity: 0.7;
	}
}

.form-item-label {
	width: 100%;
	display: flex;
	align-items: center;
	justify-content: flex-start;
	overflow: hidden;
	text-overflow: ellipsis;
	white-space: nowrap;
}

.form-item-content {
	width: 100%;
	display: flex;
	align-items: center;
	justify-content: space-around;
}

.drag-icon {
	height: 100%;
	width: auto;

	&:hover {
		cursor: move;
	}
}
</style>
